{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #有效数字"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Medium"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: validNumber"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #有效数字"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p><strong>有效数字</strong>（按顺序）可以分成以下几个部分：</p>\n",
    "\n",
    "<ol>\n",
    "\t<li>若干空格</li>\n",
    "\t<li>一个 <strong>小数</strong> 或者 <strong>整数</strong></li>\n",
    "\t<li>（可选）一个 <code>'e'</code> 或 <code>'E'</code> ，后面跟着一个 <strong>整数</strong></li>\n",
    "\t<li>若干空格</li>\n",
    "</ol>\n",
    "\n",
    "<p><strong>小数</strong>（按顺序）可以分成以下几个部分：</p>\n",
    "\n",
    "<ol>\n",
    "\t<li>（可选）一个符号字符（<code>'+'</code> 或 <code>'-'</code>）</li>\n",
    "\t<li>下述格式之一：\n",
    "\t<ol>\n",
    "\t\t<li>至少一位数字，后面跟着一个点 <code>'.'</code></li>\n",
    "\t\t<li>至少一位数字，后面跟着一个点 <code>'.'</code> ，后面再跟着至少一位数字</li>\n",
    "\t\t<li>一个点 <code>'.'</code> ，后面跟着至少一位数字</li>\n",
    "\t</ol>\n",
    "\t</li>\n",
    "</ol>\n",
    "\n",
    "<p><strong>整数</strong>（按顺序）可以分成以下几个部分：</p>\n",
    "\n",
    "<ol>\n",
    "\t<li>（可选）一个符号字符（<code>'+'</code> 或 <code>'-'</code>）</li>\n",
    "\t<li>至少一位数字</li>\n",
    "</ol>\n",
    "\n",
    "<p>部分有效数字列举如下：<code>[\"2\", \"0089\", \"-0.1\", \"+3.14\", \"4.\", \"-.9\", \"2e10\", \"-90E3\", \"3e+7\", \"+6e-1\", \"53.5e93\", \"-123.456e789\"]</code></p>\n",
    "\n",
    "<p>部分无效数字列举如下：<code>[\"abc\", \"1a\", \"1e\", \"e3\", \"99e2.5\", \"--6\", \"-+3\", \"95a54e53\"]</code></p>\n",
    "\n",
    "<p>给你一个字符串 <code>s</code> ，如果 <code>s</code> 是一个 <strong>有效数字</strong> ，请返回 <code>true</code> 。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"0\"\n",
    "<strong>输出：</strong>true\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"e\"\n",
    "<strong>输出：</strong>false\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \".\"\n",
    "<strong>输出：</strong>false\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 &lt;= s.length &lt;= 20</code></li>\n",
    "\t<li><code>s</code> 仅含英文字母（大写和小写），数字（<code>0-9</code>），加号 <code>'+'</code> ，减号 <code>'-'</code> ，空格 <code>' '</code> 或者点 <code>'.'</code> 。</li>\n",
    "</ul>\n",
    "\n",
    "<p>&nbsp;</p>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [biao-shi-shu-zhi-de-zi-fu-chuan-lcof](https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [biao-shi-shu-zhi-de-zi-fu-chuan-lcof](https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['\"0\"', '\"e\"', '\".\"']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution: validNumber=lambda self, s: True if re.match(r'(^\\s*[\\+\\-]?\\d*\\.?\\d+([eE][\\+\\-]?\\d+)?\\s*$)|(^\\s*[\\+\\-]?\\d+\\.?\\d*([eE][\\+\\-]?\\d+)?\\s*$)', s) else False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "        return re.search(r\"^[\\+-]?\\d+\\.?\\d*([eE][\\+-]?\\d+)?$|^[+-]?\\.\\d+([eE][\\+-]?\\d+)?$\", s) is not None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        lst = s.strip()\n",
    "        # lst = list(s)\n",
    "        i = 0\n",
    "        decimal_point = 0\n",
    "        is_num = 0\n",
    "        e_E = 0\n",
    "        while i < len(lst):\n",
    "            if lst[i].isdigit():\n",
    "                i = i + 1\n",
    "                is_num = 1\n",
    "            elif lst[i] == '+' or lst[i] == '-':\n",
    "                if i == 0 and i+1 < len(lst):\n",
    "                    i = i + 1\n",
    "                else:\n",
    "                    return False\n",
    "            elif lst[i] == '.' and decimal_point == 0:\n",
    "                decimal_point = 1\n",
    "                if is_num == 0:\n",
    "                    if i == len(lst) - 1:\n",
    "                        return False\n",
    "                    else:\n",
    "                        if lst[i+1].isdigit():\n",
    "                            i = i + 1\n",
    "                        else:\n",
    "                            False\n",
    "                else:\n",
    "                    i = i + 1\n",
    "            elif lst[i] == 'e' or lst[i] == 'E':\n",
    "                if e_E == 0:\n",
    "                    if i == 0 or i == len(lst)-1 or is_num == 0:\n",
    "                        return False\n",
    "                    else:\n",
    "                        lst = lst[i+1:]\n",
    "                        i = 0\n",
    "                        decimal_point = 1\n",
    "                        is_num = 0\n",
    "                        e_E = 1\n",
    "                else:\n",
    "                    return False\n",
    "            else:\n",
    "                return False\n",
    "        if len(lst) == 0:\n",
    "            return False\n",
    "        else:\n",
    "            return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s=s.strip()\n",
    "        parram=r'^[+-]?((\\d+\\.?\\d?)|(\\d?\\.?\\d+)|(\\d+\\.\\d+))([eE][+-]?\\d+)?$'\n",
    "        a=re.match(parram,s)\n",
    "        print(a)\n",
    "        return not a==None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "\n",
    "        if len(s) == 0:\n",
    "            return False\n",
    "\n",
    "        if s[0] in [\"+\", \"-\"]:\n",
    "            s = s[1:]\n",
    "\n",
    "        # 注：有 e 无 . ; 有 . 无 e\n",
    "        # 记录 .\n",
    "        point_is_appear = False\n",
    "        # 记录 e E\n",
    "        e_is_appear = False\n",
    "        # 记录 + -\n",
    "        symbol_is_appear = False\n",
    "        # 记录 e E 之前的数字\n",
    "        digit_is_appear = False\n",
    "\n",
    "        for _ in range(len(s)):\n",
    "            char = s[_]\n",
    "            # 如果 . 第一次出现可以继续向下遍历，且不能有 e E\n",
    "            if char == \".\" and not point_is_appear and not e_is_appear:\n",
    "                point_is_appear = True\n",
    "            # 如果再次出现 + - 且 前一个元素是 e E 的话，可以继续向下遍历\n",
    "            elif char in [\"+\", \"-\"] and e_is_appear and s[_ - 1] in [\"e\", \"E\"]:\n",
    "                symbol_is_appear = True\n",
    "            # 如果第一次出现e或E，可以继续向下遍历\n",
    "            elif char in [\"e\", \"E\"] and not e_is_appear:\n",
    "                e_is_appear = True\n",
    "            # 如果是数字，可以继续向下运行\n",
    "            elif char.isdigit():\n",
    "                # 如果 e E 之前出现过数字，记录下\n",
    "                if not e_is_appear:\n",
    "                    digit_is_appear = True\n",
    "            else:\n",
    "                return False\n",
    "\n",
    "        # 如果最后一个元素为 e E 返回False\n",
    "        if s[-1] in [\"e\", \"E\"]:\n",
    "            return False\n",
    "        # 如果 e E 出现过，但是前面没有任何数字 返回False\n",
    "        elif e_is_appear and not digit_is_appear:\n",
    "            return False\n",
    "        # 如果 . 只出现过一次，返回False\n",
    "        elif point_is_appear and len(s) == 1:\n",
    "            return False\n",
    "        # 如果 + - 出现了一次，但是后面没有数字，返回False\n",
    "        elif symbol_is_appear and not s[-1].isdigit():\n",
    "            return False\n",
    "\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            {' ': 0, 's': 1, 'd': 2, '.': 4},   # 0. ' '\n",
    "            {'d': 2, '.': 4},                   # 1. '+-' before 'eE'\n",
    "            {'d': 2, '.': 3, 'e': 5, ' ': 8},   # 2. '0'~'9' before '.'\n",
    "            {'d': 3, 'e': 5, ' ': 8},           # 3. '0'~'9' after '.'\n",
    "            {'d': 3},                           # 4. '0'~'9' after '.' without prior '0'~'9'\n",
    "            {'s': 6, 'd': 7},                   # 5. 'eE'\n",
    "            {'d': 7},                           # 6. '+-' after 'eE'\n",
    "            {'d': 7, ' ': 8},                   # 7. '0'~'9' after 'eE'\n",
    "            {' ': 8}                            # 8. ' '\n",
    "        ]\n",
    "\n",
    "        cur = 0\n",
    "        for c in s:\n",
    "            if c.isdigit(): t = 'd'\n",
    "            elif c in \"+-\": t = 's'\n",
    "            elif c in \"eE\": t = 'e'\n",
    "            elif c in \". \": t = c\n",
    "            else: t = '?'\n",
    "            if t not in states[cur]: return False\n",
    "            cur = states[cur][t]\n",
    "        return cur in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        import re\n",
    "        p = re.compile(r'^[+-]?(\\.\\d+|\\d+\\.?\\d*)([eE][+-]?\\d+)?$')\n",
    "        return bool(p.match(s.strip()))\n",
    "\n",
    "\n",
    "        matches = re.match('[ ]*[+-]?[\\d+\\.|\\d+\\.\\d+|\\.\\d+|\\d+][[eE][+-]?\\d+]?[]*$', s)\n",
    "        if matches:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n",
    "        p = re.compile(r'^[+-]?(\\.\\d+|\\d+\\.?\\d*)([eE][+-]?\\d+)?$')\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        return bool(self.p.match(s.strip()))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()  # 删除字符串头尾的空格\n",
    "        isNum = False\n",
    "        isDot = False\n",
    "        ise_or_E = False  # 标记是否遇到数位、小数点、‘e’或'E'\n",
    "        for i in range(len(s)):\n",
    "            if '0' <= s[i] <= '9': \n",
    "                isNum = True  # 判断当前字符是否为 0~9 的数位\n",
    "            elif s[i] == '.':  # 遇到小数点\n",
    "                if isDot or ise_or_E: \n",
    "                    return False  # 小数点之前可以没有整数，但是不能重复出现小数点、或出现‘e’、'E'\n",
    "                isDot = True  # 标记已经遇到小数点\n",
    "            elif s[i] == 'e' or s[i] == 'E':  # 遇到‘e’或'E'\n",
    "                if not isNum or ise_or_E: \n",
    "                    return False  # ‘e’或'E'前面必须有整数，且前面不能重复出现‘e’或'E'\n",
    "                ise_or_E = True  # 标记已经遇到‘e’或'E'\n",
    "                isNum = False  # 重置isNum，因为‘e’或'E'之后也必须接上整数，防止出现 123e或者123e+的非法情况\n",
    "            elif s[i] == '-' or s[i] == '+':\n",
    "                if i != 0 and s[i-1] != 'e' and s[i-1] != 'E': \n",
    "                    return False  # 正负号只可能出现在第一个位置，或者出现在‘e’或'E'的后面一个位置\n",
    "            else: \n",
    "                return False  # 其它情况均为不合法字符\n",
    "        return isNum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def is_integer(self,s:str)-> bool:\n",
    "        if s[0] == '-' or s[0] == '+':\n",
    "            return s[1:].isdigit()\n",
    "        else:\n",
    "            return s.isdigit()\n",
    "\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            float(s)\n",
    "        except:\n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, \n",
    "            { 'd': 2, '.': 4 } ,                \n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, \n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         \n",
    "            { 'd': 3 },                        \n",
    "            { 's': 6, 'd': 7 },                 \n",
    "            { 'd': 7 },                         \n",
    "            { 'd': 7, ' ': 8 },                 \n",
    "            { ' ': 8 }                          \n",
    "        ]\n",
    "        p = 0                           \n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' \n",
    "            elif c in \"+-\": t = 's'     \n",
    "            elif c in \"eE\": t = 'e'     \n",
    "            elif c in \". \": t = c       \n",
    "            else: t = '?'               \n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s_list=s.split()\n",
    "        # 去除空格\n",
    "        if len(s_list)!=1:\n",
    "            return False\n",
    "        s=s_list[0]\n",
    "        # 顺序为 sig int . int E/e sig int\n",
    "        def isInt(s):\n",
    "            L=len(s)\n",
    "            num=\"0123456789\"\n",
    "            if L==0 or ( L==1 and s not in num ):\n",
    "                return False\n",
    "            if s[0] not in \"+-\" and s[0] not in num:\n",
    "                return False\n",
    "            for i in range(1,L):\n",
    "                if s[i] not in num:\n",
    "                    return False\n",
    "            return True\n",
    "        \n",
    "        # 查看是否有e\n",
    "        if s[-1]=='e' or s[-1]=='E' or s[0] not in \"+-0123456789.\":\n",
    "            return False\n",
    "        s=s.replace('E','e')\n",
    "        e_list=s.split('e')\n",
    "        # 理应为1或2\n",
    "        if len(e_list)!=1 and len(e_list)!=2:\n",
    "            return False\n",
    "        # 如果为2，代表有e\n",
    "        if len(e_list)==2:\n",
    "            if not isInt(e_list[-1]):\n",
    "                return False\n",
    "        s=e_list[0]\n",
    "        # 现在s没有e了，那么必须是小数或整数\n",
    "        if isInt(s):\n",
    "            return True\n",
    "        # 必须是小数\n",
    "        if s[0]=='.':\n",
    "            if isInt(s[1:]) and s[1] in \"0123456789\":\n",
    "                return True\n",
    "        if s[-1]=='.':\n",
    "            if isInt(s[0:-1]):\n",
    "                return True\n",
    "        p_list=s.split('.')\n",
    "        if len(p_list)!=2:\n",
    "            return False\n",
    "        if not isInt(p_list[-1]):\n",
    "            return False\n",
    "        if len(p_list[0])==1 and p_list[0] in \"+-\":\n",
    "            return True\n",
    "        if not isInt(p_list[0]):\n",
    "            return False\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:            \n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "        return re.search(r\"^[\\+-]?\\d+\\.?\\d*([eE][\\+-]?\\d+)?$|^[+-]?\\.\\d+([eE][\\+-]?\\d+)?$\", s) is not None\n",
    "        # try:\n",
    "        #     a = s.lower().strip()\n",
    "        #     if a.startswith('0'):\n",
    "        #         a = '1'+a.lstrip('0')\n",
    "        #     if a.startswith('-0'):\n",
    "        #         a = '1'+a.lstrip('-0')\n",
    "        #     print(a)\n",
    "        #     if a.endswith('e') or a.endswith('e.'):\n",
    "        #         return False\n",
    "        #     a = a.replace('e','*1')\n",
    "        #     # print(a)\n",
    "        #     a = float(eval(a))\n",
    "        #     return True\n",
    "        # except Exception as e:\n",
    "        #     return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "     def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "        flag_e = False\n",
    "        flag_p = False\n",
    "        flag_n = False\n",
    "        for i in range(len(s)):\n",
    "            if s[i] in (\"+\",\"-\"):\n",
    "                if i !=0 and (s[i-1] not in (\"e\",\"E\")):\n",
    "                    return False\n",
    "            elif s[i] == \".\":\n",
    "                if flag_e or flag_p:\n",
    "                    return False\n",
    "                flag_p = True\n",
    "            elif \"0\"<=s[i]<=\"9\":\n",
    "                flag_n = True\n",
    "            elif s[i] in (\"e\",\"E\"):\n",
    "                if flag_e or (not flag_n):\n",
    "                    return False\n",
    "                flag_e = True\n",
    "                flag_n = False\n",
    "            else:\n",
    "                return False\n",
    "        return flag_n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        try:\n",
    "            float(s)\n",
    "        except:\n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        \n",
    "        try:\n",
    "            float(s)\n",
    "            return True\n",
    "        except:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        # 有限自动机\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)  # 合法的结束状态有 2, 3, 7, 8 。\n",
    "\n",
    "        import re\n",
    "        # 状态机 self\n",
    "        matches = re.match(r'^[+-]?(\\d+\\.|\\d+\\.\\d+|\\.\\d+|\\d+)([eE][+-]?\\d+)?$', s.strip())\n",
    "        return bool(matches)\n",
    "        \n",
    "        # 状态机\n",
    "        p = re.compile(r'^[+-]?(\\.\\d+|\\d+\\.?\\d*)([eE][+-]?\\d+)?$')\n",
    "        return bool(p.match(s.strip()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isNumber(self, s: str) -> bool:\n",
    "        n, l, r = len(s), 0, len(s) - 1\n",
    "        while l < n and s[l] == ' ':\n",
    "            l += 1\n",
    "        while r >= 0 and s[r] == ' ':\n",
    "            r -= 1\n",
    "        if l > r:\n",
    "            return False\n",
    "        s = s[l:r + 1].replace('e', 'E')\n",
    "        n, idx = len(s), 0\n",
    "        while idx < n and s[idx] != 'E':\n",
    "            idx += 1\n",
    "        if idx == n:\n",
    "            return self.check(s, True)\n",
    "        else:\n",
    "            return self.check(s[:idx], True) and self.check(s[idx + 1:], False)\n",
    "            \n",
    "    def check(self, s: str, is_decimal: bool) -> bool:\n",
    "        if s == \".\" or s == \"\":\n",
    "            return False\n",
    "        n, cnt = len(s), 0\n",
    "        for i in range(n):\n",
    "            c = s[i]\n",
    "            if c == '+' or c == '-':\n",
    "                if i != 0 or i == n - 1:\n",
    "                    return False\n",
    "            elif c == '.':\n",
    "                if not is_decimal:\n",
    "                    return False\n",
    "                if cnt != 0:\n",
    "                    return False\n",
    "                a = i - 1 >= 0 and s[i - 1].isdigit()\n",
    "                b = i + 1 < n and s[i + 1].isdigit()\n",
    "                if not (a or b):\n",
    "                    return False\n",
    "                cnt += 1\n",
    "            elif not c.isdigit():\n",
    "                return False\n",
    "        return True\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        return Solution.isNumber(self,s)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n",
    "\n",
    "#见链接：https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/?envType=study-plan-v2&envId=coding-interviews"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "num_list = ['0','1','2','3','4','5','6','7','8','9']\n",
    "\n",
    "class Automation:\n",
    "    def __init__(self):\n",
    "        self.state = 'start'\n",
    "        self.result = False\n",
    "        self.node_cnt = 0\n",
    "        self.num_before_node = 0\n",
    "        self.table = {\n",
    "            'start':['start','signed','num','end','node','end'],\n",
    "            'signed':['end','end','num','end','node','end'],\n",
    "            'node':['end','end','num','end','end','end'],\n",
    "            'num':['end','end','num','more','node','end'],\n",
    "            'more':['end','zz-signed','zz','end','end','end'],\n",
    "            'zz-signed':['end','end','zz','end','end','end'],\n",
    "            'zz':['end','end','zz','end','end','end'],\n",
    "            'end':['end','end','end','end','end','end']\n",
    "        }\n",
    "    def get_col(self,c):\n",
    "        if c == \" \":\n",
    "            return 0\n",
    "        elif c == \"+\" or c == \"-\":\n",
    "            return 1\n",
    "        elif c in num_list:\n",
    "            return 2\n",
    "        elif c == \"e\" or c == \"E\":\n",
    "            return 3\n",
    "        elif c == \".\":\n",
    "            self.node_cnt += 1\n",
    "            return 4\n",
    "        else:\n",
    "            return 5\n",
    "\n",
    "    def change_state(self,c):\n",
    "        if c in num_list and self.node_cnt == 0:\n",
    "            self.num_before_node = 1\n",
    "\n",
    "        if self.state == 'node':\n",
    "            if c == \"e\" or c == \"E\":\n",
    "                if self.num_before_node == 1:\n",
    "                    self.state = 'more'\n",
    "                    return\n",
    "                else:\n",
    "                    self.state = self.table[self.state][self.get_col(c)]\n",
    "                    return\n",
    "\n",
    "        if self.state == 'num':\n",
    "            if_node = self.get_col(c)\n",
    "            if if_node == 4 and self.node_cnt==1:\n",
    "                self.state = self.table[self.state][if_node]\n",
    "            elif if_node == 4 and self.node_cnt > 1:\n",
    "                self.state = 'end'\n",
    "            else:\n",
    "                self.state = self.table[self.state][self.get_col(c)]\n",
    "        else:\n",
    "            self.state = self.table[self.state][self.get_col(c)]\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        true_state = ['num','zz']\n",
    "        s = s.strip()\n",
    "        if not s:return False\n",
    "        my_auto = Automation()\n",
    "        for i in s:\n",
    "            my_auto.change_state(i)\n",
    "        if my_auto.node_cnt > 1:\n",
    "            return False\n",
    "        elif my_auto.state in true_state:\n",
    "            return True\n",
    "        elif my_auto.state == 'node' and my_auto.num_before_node == 1:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    my_so = Solution()\n",
    "    temp = \"46.e3\"\n",
    "    print(my_so.validNumber(temp))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "num_list = ['0','1','2','3','4','5','6','7','8','9']\n",
    "\n",
    "class Automation:\n",
    "    def __init__(self):\n",
    "        self.state = 'start'\n",
    "        self.result = False\n",
    "        self.node_cnt = 0\n",
    "        self.num_before_node = 0\n",
    "        self.table = {\n",
    "            'start':['start','signed','num','end','node','end'],\n",
    "            'signed':['end','end','num','end','node','end'],\n",
    "            'node':['end','end','num','end','end','end'],\n",
    "            'num':['end','end','num','more','node','end'],\n",
    "            'more':['end','zz-signed','zz','end','end','end'],\n",
    "            'zz-signed':['end','end','zz','end','end','end'],\n",
    "            'zz':['end','end','zz','end','end','end'],\n",
    "            'end':['end','end','end','end','end','end']\n",
    "        }\n",
    "    def get_col(self,c):\n",
    "        if c == \" \":\n",
    "            return 0\n",
    "        elif c == \"+\" or c == \"-\":\n",
    "            return 1\n",
    "        elif c in num_list:\n",
    "            return 2\n",
    "        elif c == \"e\" or c == \"E\":\n",
    "            return 3\n",
    "        elif c == \".\":\n",
    "            self.node_cnt += 1\n",
    "            return 4\n",
    "        else:\n",
    "            return 5\n",
    "\n",
    "    def change_state(self,c):\n",
    "        if c in num_list and self.node_cnt == 0:\n",
    "            self.num_before_node = 1\n",
    "\n",
    "        if self.state == 'node':\n",
    "            if c == \"e\" or c == \"E\":\n",
    "                if self.num_before_node == 1:\n",
    "                    self.state = 'more'\n",
    "                    return\n",
    "                else:\n",
    "                    self.state = self.table[self.state][self.get_col(c)]\n",
    "                    return\n",
    "\n",
    "        if self.state == 'num':\n",
    "            if_node = self.get_col(c)\n",
    "            if if_node == 4 and self.node_cnt==1:\n",
    "                self.state = self.table[self.state][if_node]\n",
    "            elif if_node == 4 and self.node_cnt > 1:\n",
    "                self.state = 'end'\n",
    "            else:\n",
    "                self.state = self.table[self.state][self.get_col(c)]\n",
    "        else:\n",
    "            self.state = self.table[self.state][self.get_col(c)]\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        true_state = ['num','zz']\n",
    "        s = s.strip()\n",
    "        if not s:return False\n",
    "        my_auto = Automation()\n",
    "        for i in s:\n",
    "            my_auto.change_state(i)\n",
    "        if my_auto.node_cnt > 1:\n",
    "            return False\n",
    "        elif my_auto.state in true_state:\n",
    "            return True\n",
    "        elif my_auto.state == 'node' and my_auto.num_before_node == 1:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        if not s:\n",
    "            return False\n",
    "        \n",
    "        states = [\n",
    "            {' ': 0, 's': 1, 'd': 2, '.': 4}, # 开始状态\n",
    "            {'d': 2, '.': 4}, # 状态1的转移\n",
    "            {'d': 2, '.': 3, 'e': 5, ' ': 8}, # 状态2的转移\n",
    "            {'d': 3, 'e': 5, ' ': 8}, # 状态3的转移\n",
    "            {'d': 3}, # 状态4的转移\n",
    "            {'s': 6, 'd': 7}, # 状态5的转移\n",
    "            {'d': 7}, # 状态6的转移\n",
    "            {'d': 7, ' ': 8}, # 状态7的转移\n",
    "            {' ': 8} # 状态8的转移\n",
    "        ]\n",
    "\n",
    "        cur = 0\n",
    "\n",
    "        for char in s:\n",
    "            if char in \"0123456789\":\n",
    "                temp = 'd'\n",
    "            elif char in \"+-\":\n",
    "                temp = 's'\n",
    "            elif char in \"eE\":\n",
    "                temp = 'e'\n",
    "            elif char in \". \":\n",
    "                temp = char\n",
    "            else:\n",
    "                temp = '?'\n",
    "            \n",
    "            if temp not in states[cur]:\n",
    "                return False\n",
    "            \n",
    "            cur = states[cur][temp]\n",
    "        \n",
    "        return cur in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#每个 DFA 都有与之对应的正规式。\n",
    "#许多语言都可以解析正规式并生成对应的 DFA 或 NFA。\n",
    "#有穷自动机(finite state automata)是一个识别器，它对每个输入的字符做识别和判断，以确定其能到达的最终状态或状态集和路径，有穷自动机分为两类，即不确定的有穷自动机NFA和确定的有穷自动机DFA\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        d='([+-]?((\\d+\\.)|(\\d+\\.\\d+)|(\\.\\d+)))'\n",
    "        i='([+-]?\\d+)'\n",
    "        return True if re.fullmatch(f' *({i}|{d})([eE]{i})? *',s) else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s):\n",
    "        def isInteger(str):\n",
    "            if len(str) == 0:\n",
    "                return False\n",
    "            if str[0] == '+' or str[0] == '-':\n",
    "                str = str[1:]\n",
    "            return str.isdigit()\n",
    "        def isDicimal(str):\n",
    "            if len(str) == 0:\n",
    "                return False\n",
    "            if str[0] == '+' or str[0] == '-':\n",
    "                str = str[1:]\n",
    "            l = str.split('.')\n",
    "            if len(l) != 2:\n",
    "                return False\n",
    "            if len(l[0]) == 0:\n",
    "                return l[1].isdigit()\n",
    "            if len(l[1]) == 0:\n",
    "                return l[0].isdigit()\n",
    "            return l[0].isdigit() and l[1].isdigit()\n",
    "        s = s.strip()\n",
    "        if 'e' in s:\n",
    "            a = s.split('e')\n",
    "            if len(a[0]) == 0 or len(a[1]) == 0 or len(a) != 2:\n",
    "                return False\n",
    "            return (isInteger(a[0]) or isDicimal(a[0])) and isInteger(a[1])\n",
    "        if 'E' in s:\n",
    "            a = s.split('E')\n",
    "            if len(a[0]) == 0 or len(a[1]) == 0 or len(a) != 2:\n",
    "                return False\n",
    "            return (isInteger(a[0]) or isDicimal(a[0])) and isInteger(a[1])\n",
    "        return isDicimal(s) or isInteger(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        return re.search(r'^\\s*[+-]?(\\d+|(\\d*\\.\\d+)|(\\d+\\.\\d*))([eE][+-]?\\d+)?\\s*$', s) is not None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            {' ':0, 's':1, 'd':2, '.':4},\n",
    "            {'d':2, '.':4},\n",
    "            {'d':2, '.':3, 'e':5, ' ':8},\n",
    "            {'d':3, 'e':5, ' ':8},\n",
    "            {'d':3},\n",
    "            {'s':6, 'd':7},\n",
    "            {'d':7},\n",
    "            {'d':7, ' ':8},\n",
    "            {' ':8}\n",
    "        ]\n",
    "        p = 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9':\n",
    "                t = 'd'\n",
    "            elif c in '+-':\n",
    "                t = 's'\n",
    "            elif c in 'eE':\n",
    "                t = 'e'\n",
    "            elif c in '. ':\n",
    "                t = c\n",
    "            else:\n",
    "                t = '?'\n",
    "            if t not in states[p]:\n",
    "                return False\n",
    "            p = states[p][t]\n",
    "        return p in (2,3,7,8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, \n",
    "            { 'd': 2, '.': 4 } ,               \n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, \n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         \n",
    "            { 'd': 3 },                        \n",
    "            { 's': 6, 'd': 7 },                \n",
    "            { 'd': 7 },                         \n",
    "            { 'd': 7, ' ': 8 },                 \n",
    "            { ' ': 8 }                         \n",
    "        ]\n",
    "        p = 0                           \n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' \n",
    "            elif c in \"+-\": t = 's'     \n",
    "            elif c in \"eE\": t = 'e'     \n",
    "            elif c in \". \": t = c       \n",
    "            else: t = '?'               \n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "        if 'e' in s:\n",
    "            l = s.split('e')\n",
    "            if len(l) != 2 or len(l[0]) == 0 or len(l[1]) == 0:\n",
    "                return False\n",
    "            return (isInteger(l[0]) or isDicimal(l[0])) and isInteger(l[1])\n",
    "        elif 'E' in s:\n",
    "            l = s.split('E')\n",
    "            if len(l) != 2 or len(l[0]) == 0 or len(l[1]) == 0:\n",
    "                return False\n",
    "            return (isInteger(l[0]) or isDicimal(l[0])) and isInteger(l[1])\n",
    "        else:\n",
    "            return isInteger(s) or isDicimal(s)\n",
    "def isDicimal(s):\n",
    "    if len(s) == 0: return False\n",
    "    if s[0] == '+' or s[0] == '-':\n",
    "        s = s[1:]\n",
    "    l = s.split('.')\n",
    "    if len(l) != 2:  # there is no '.' or more than one '.'\n",
    "        return False\n",
    "    if len(l[0]) == 0:  #  no number before '.', e.g., '.23'\n",
    "        return l[1].isdigit()\n",
    "    if len(l[1]) == 0:  # no number after '.', e.g., '23.'\n",
    "        return l[0].isdigit()\n",
    "    return l[0].isdigit() and l[1].isdigit()\n",
    "\n",
    "def isInteger(s):\n",
    "    if len(s) == 0: return False\n",
    "    if s[0] == '+' or s[0] == '-':\n",
    "        s = s[1:]\n",
    "    return s.isdigit()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        stats = [\n",
    "            {' ':0, 's':1, 'd':2, '.':4},\n",
    "            {'d':2, '.':4},\n",
    "            {'d':2, ' ':8, 'e':5, '.':3},\n",
    "            {'d':3, 'e':5, ' ':8},\n",
    "            {'d':3},\n",
    "            {'s':5, 'd':7},\n",
    "            {'d':7},\n",
    "            {'d':7, ' ':8},\n",
    "            {' ':8}\n",
    "        ]\n",
    "        p = 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd'\n",
    "            elif c in '+-': t = 's'\n",
    "            elif c in 'Ee': t = 'e'\n",
    "            elif c in '. ': t = c\n",
    "            else: t = '?'\n",
    "            if t not in stats[p]: return False\n",
    "            p = stats[p][t]\n",
    "        return True if p in [2,3,7,8] else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "     def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        pattern = r'^\\s*[-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?\\s*$'\n",
    "        if re.match(pattern, s):\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "# ^：匹配字符串的开头\n",
    "# \\s*：匹配零个或多个空格\n",
    "# [-+]?：可选的正负号\n",
    "# (\\d+(\\.\\d*)?|\\.\\d+)：匹配小数或整数部分。它由两部分组成：\n",
    "# \\d+(\\.\\d*)?：匹配至少一位数字，可选地后跟小数部分（由一个点和零个或多个数字组成）。\n",
    "# |\\.\\d+：匹配一个点后跟至少一位数字的小数。\n",
    "# ([eE][-+]?\\d+)?：可选的指数部分。它由以下内容组成：\n",
    "# [eE]：匹配字母e或E。\n",
    "# [-+]?：可选的正负号。\n",
    "# \\d+：匹配至少一位数字。\n",
    "# \\s*：匹配零个或多个空格\n",
    "# $：匹配字符串的结尾\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "\n",
    "        if len(s) == 0:\n",
    "            return False\n",
    "        if all(\n",
    "            not self.isDigit(i) for i in s\n",
    "        ):\n",
    "            return False\n",
    "        \n",
    "        num_flag = False\n",
    "        dot_flag = False\n",
    "        e_flag = False\n",
    "        # 1. e后面不能出现dot\n",
    "        # 2. e前面必须出现数字\n",
    "        # 3. e不能出现两次\n",
    "        # 4. dot不能出现两次\n",
    "        # 5. e后面也需要有数字\n",
    "        for index, item in enumerate(s):\n",
    "            if self.isDigit(item):\n",
    "                num_flag = True\n",
    "            elif item == '.':\n",
    "                if dot_flag is False and e_flag is False: # 4 + 1\n",
    "                    dot_flag = True\n",
    "                else:\n",
    "                    return False\n",
    "            elif item in \"eE\":\n",
    "                if num_flag is False or e_flag is True: # 2 + 3\n",
    "                    return False\n",
    "                else:\n",
    "                    e_flag = True\n",
    "                    num_flag = False # 5\n",
    "            elif item in \"+-\":\n",
    "                # 正负号出现在最开头或者e后面\n",
    "                if index == 0:\n",
    "                    pass\n",
    "                elif (index-1 >= 0 and s[index-1] in \"eE\") \\\n",
    "                    and (index+1 <= len(s)-1 and self.isDigit(s[index+1])):\n",
    "                    pass\n",
    "                else:\n",
    "                    return False\n",
    "            else:\n",
    "                return False\n",
    "\n",
    "        return num_flag\n",
    "\n",
    "    def isDigit(self, s: str) -> bool:\n",
    "        if len(s) <= 0 or len(s) >= 2:\n",
    "            raise ValueError()\n",
    "        return ord(s) <= ord(\"9\") and ord(s) >= ord(\"0\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        if re.search(\"^[-|+]?(\\d+\\.?(\\d+)?|(\\d+)?\\.\\d+)([e|E][-|+]?\\d+)?$\", s.strip()):\n",
    "            return True\n",
    "        else:\n",
    "            return False  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            {' ': 0, 's': 1, 'd': 2, '.': 4},\n",
    "            {'.': 4, 'd': 2},\n",
    "            {'d': 2, '.': 3, 'e': 5, ' ': 8},\n",
    "            {'d': 3, 'e': 5, ' ': 8},\n",
    "            {'d': 3},\n",
    "            {'s': 6, 'd': 7},\n",
    "            {'d': 7},\n",
    "            {'d': 7, ' ': 8},\n",
    "            {' ': 8}\n",
    "        ]\n",
    "        p = 0\n",
    "        for i in s:\n",
    "            if '0' <= i <= '9':\n",
    "                t = 'd'\n",
    "            elif i in \"+-\":\n",
    "                t = 's'\n",
    "            elif i in \" .\":\n",
    "                t = i\n",
    "            elif i in \"eE\":\n",
    "                t = 'e'\n",
    "            else:\n",
    "                t = '?'\n",
    "            if t not in states[p]:\n",
    "                return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            {'b': 0, 's': 1, 'd': 2, 'c': 4},\n",
    "            {'d': 2, 'c': 4},\n",
    "            {'d': 2, 'c': 3, 'e': 5, 'b': 8},\n",
    "            {'d': 3, 'e': 5, 'b': 8},\n",
    "            {'d': 3},\n",
    "            {'d': 7, 's': 6},\n",
    "            {'d': 7},\n",
    "            {'d': 7, 'b': 8},\n",
    "            {'b': 8}\n",
    "        ]\n",
    "\n",
    "        p = 0\n",
    "        for c in s:\n",
    "            if c == ' ':\n",
    "                t = 'b'\n",
    "            elif c in '+-':\n",
    "                t = 's'\n",
    "            elif c == '.':\n",
    "                t = 'c'\n",
    "            elif c in 'eE':\n",
    "                t = 'e'\n",
    "            elif c in '0123456789':\n",
    "                t = 'd'\n",
    "            else:\n",
    "                t = '?'\n",
    "            if t not in states[p]:\n",
    "                return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from enum import Enum\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        State = Enum(\"State\", [\n",
    "            \"STATE_INITIAL\",\n",
    "            \"STATE_INT_SIGN\",\n",
    "            \"STATE_INTEGER\",\n",
    "            \"STATE_POINT\",\n",
    "            \"STATE_POINT_WITHOUT_INT\",\n",
    "            \"STATE_FRACTION\",\n",
    "            \"STATE_EXP\",\n",
    "            \"STATE_EXP_SIGN\",\n",
    "            \"STATE_EXP_NUMBER\",\n",
    "            \"STATE_END\"\n",
    "        ])\n",
    "        Chartype = Enum(\"Chartype\", [\n",
    "            \"CHAR_NUMBER\",\n",
    "            \"CHAR_EXP\",\n",
    "            \"CHAR_POINT\",\n",
    "            \"CHAR_SIGN\",\n",
    "            \"CHAR_SPACE\",\n",
    "            \"CHAR_ILLEGAL\"\n",
    "        ])\n",
    "\n",
    "        def toChartype(ch: str) -> Chartype:\n",
    "            if ch.isdigit():\n",
    "                return Chartype.CHAR_NUMBER\n",
    "            elif ch.lower() == \"e\":\n",
    "                return Chartype.CHAR_EXP\n",
    "            elif ch == \".\":\n",
    "                return Chartype.CHAR_POINT\n",
    "            elif ch == \"+\" or ch == \"-\":\n",
    "                return Chartype.CHAR_SIGN\n",
    "            elif ch == \" \":\n",
    "                return Chartype.CHAR_SPACE\n",
    "            else:\n",
    "                return Chartype.CHAR_ILLEGAL\n",
    "        \n",
    "        transfer = {\n",
    "            State.STATE_INITIAL: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_INITIAL,\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT,\n",
    "                Chartype.CHAR_SIGN: State.STATE_INT_SIGN\n",
    "            },\n",
    "            State.STATE_INT_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT\n",
    "            },\n",
    "            State.STATE_INTEGER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT_WITHOUT_INT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION\n",
    "            },\n",
    "            State.STATE_FRACTION: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_EXP: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SIGN: State.STATE_EXP_SIGN\n",
    "            },\n",
    "            State.STATE_EXP_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "            State.STATE_EXP_NUMBER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_END: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "        }\n",
    "\n",
    "        st = State.STATE_INITIAL\n",
    "        for ch in s:\n",
    "            typ = toChartype(ch)\n",
    "            if typ not in transfer[st]:\n",
    "                return False\n",
    "            st = transfer[st][typ]\n",
    "        \n",
    "        return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER, State.STATE_END]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        num = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}\n",
    "\n",
    "        def validN(s):\n",
    "            if len(s) == 0 :\n",
    "                return False\n",
    "            index = 0\n",
    "            if s[0] == '-' or s[0] == '+' :\n",
    "                index += 1\n",
    "            while index < len(s):\n",
    "                i = s[index]\n",
    "                if i not in num :\n",
    "                    return False\n",
    "                index +=1\n",
    "            if s[-1] not in num:\n",
    "                return False \n",
    "            return True\n",
    "\n",
    "        def validS(s) :\n",
    "            if len(s) == 0 :\n",
    "                return False\n",
    "            index = 0 \n",
    "            if s[0] == '+' or s[0] == '-':\n",
    "                index += 1\n",
    "            \n",
    "            if index < len(s) and s[index] == '.':\n",
    "                index += 1\n",
    "                while index < len(s) :\n",
    "                    if s[index] not in num :\n",
    "                        return False\n",
    "                    else :\n",
    "                        index += 1\n",
    "                if s[-1] not in num :\n",
    "                    return False\n",
    "                else :\n",
    "                    return True\n",
    "            \n",
    "            elif index < len(s) and s[index] in num :\n",
    "                while index < len(s) and s[index] in num :\n",
    "                    index += 1\n",
    "                if index< len(s) and s[index] != '.' : \n",
    "                    return False\n",
    "                if index == len(s)-1 :\n",
    "                    return True\n",
    "                index += 1\n",
    "                while index < len(s) :\n",
    "                    if s[index] in num :\n",
    "                        index += 1\n",
    "                    else :\n",
    "                        return False\n",
    "                if s[-1] not in num :\n",
    "                    return False\n",
    "                else :\n",
    "                    return True\n",
    "            else :\n",
    "                return False\n",
    "                \n",
    "\n",
    "\n",
    "\n",
    "        s = s.strip()\n",
    "        E = s.find('E')\n",
    "        e = s.find('e')\n",
    "\n",
    "        if E == -1 and e == -1 :\n",
    "            return validN(s) or validS(s)\n",
    "        else :\n",
    "            flag = max(E, e)\n",
    "            # print(s[:flag], s[flag:])\n",
    "            # print(validN(s[:flag]), validS(s[:flag]), validN(s[flag+1:]))\n",
    "            return (validN(s[:flag]) or validS(s[:flag])) and validN(s[flag+1:])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        \"\"\"\n",
    "        有限自动机，定义9种状态\n",
    "        0 开始的空格 1 幂符号前的正负号 2 小数点前的数字 3 小数点、小数点后的数字\n",
    "        4 当前小数前为空格时 小数点 小数点后的数字 5 幂符号 6 幂符号后的正负号 7幂符号后的数字\n",
    "        8 结尾的空格\n",
    "        合法结束状态 2 3 7 8\n",
    "        \"\"\"\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n",
    "\n",
    "            \n",
    "                \n",
    "\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        \n",
    "        s = s.strip()\n",
    "        ans = False\n",
    "        arr = []\n",
    "        # print(s)\n",
    "        if len(s) == 0:return False\n",
    "        if 'e' in s:\n",
    "            arr = s.split('e')\n",
    "            # print(arr)\n",
    "            if len(arr) > 2:\n",
    "                return False\n",
    "            else:\n",
    "                i = 0\n",
    "                if arr[0] == '' or arr[1] == '':\n",
    "                    return False\n",
    "                elif arr[0] != '' and (arr[0][0] == '+' or arr[0][0] == '-'):\n",
    "                    arr[0] = arr[0][1:]\n",
    "                if arr[1] != '' and (arr[1][0] == '+' or arr[1][0] == '-'):\n",
    "                    arr[1] = arr[1][1:]\n",
    "                ans = self.isFloatOrInt(arr[0]) and self.isInt(arr[1])\n",
    "        elif 'E' in s:\n",
    "            arr = s.split('E')\n",
    "            if len(arr) > 2:\n",
    "                return False\n",
    "            else:\n",
    "                i = 0\n",
    "                if arr[0] == '' or arr[1] == '':\n",
    "                    return False\n",
    "                elif arr[0] != '' and (arr[0][0] == '+' or arr[0][0] == '-'):\n",
    "                    arr[0] = arr[0][1:]\n",
    "                if arr[1] != '' and (arr[1][0] == '+' or arr[1][0] == '-'):\n",
    "                    arr[1] = arr[1][1:]\n",
    "                ans = self.isFloatOrInt(arr[0]) and self.isInt(arr[1])\n",
    "\n",
    "        else:\n",
    "            if s[0]== '+' or s[0] == '-':\n",
    "                s = s[1:]\n",
    "            return self.isFloatOrInt(s)\n",
    "\n",
    "        # print(arr)\n",
    "        return ans\n",
    "\n",
    "\n",
    "    def isInt(self, s: str) -> bool:\n",
    "        if s == '': return False\n",
    "        for i in s:\n",
    "            if i < '0' or i > '9':\n",
    "                return False\n",
    "        return True\n",
    "\n",
    "    def isFloatOrInt(self, s: str) -> bool:\n",
    "        if s == '': return False\n",
    "        i = 0\n",
    "        tmp = []\n",
    "        # 去符号，后续判断是否为无符号整数或小数\n",
    "        if s[i] == '+' or s[i] == '-': i += 1\n",
    "        if '.' in s[i:]:\n",
    "            tmp = s[i:].split('.')\n",
    "            if len(tmp) > 2:\n",
    "                return False\n",
    "            elif self.isInt(tmp[0]):\n",
    "                if tmp[1] == '' or self.isInt(tmp[1]):\n",
    "                    return True\n",
    "                else:\n",
    "                    return False\n",
    "            elif tmp[0] == '' and self.isInt(tmp[1]):\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        else:\n",
    "            return self.isInt(s)\n",
    "        # return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s_list=s.split()\n",
    "        # 去除前后空格\n",
    "        if len(s_list)!=1:\n",
    "            return False\n",
    "        s=s_list[0].replace('E','e')\n",
    "        num=\"0123456789\"\n",
    "        # 整数：可以有+-，但不能同时有，且至少有一个数字\n",
    "        # 小数：可以有+-，但不能同时有，有.，在.的两边至少有一个数字\n",
    "        # 数值：其余位置不能有空格，可以有E/e，但最多有一个，分割的左边可以是整数，小数右边只能是整数\n",
    "        def isInt(s):\n",
    "            nonlocal num\n",
    "            if s in [\"\",\".\",\"+\",\"-\"]:\n",
    "                return False\n",
    "            n,cnt=len(s),0\n",
    "            for i in range(n):\n",
    "                c=s[i]\n",
    "                if c in \"+-\":\n",
    "                    if i!=0:\n",
    "                        return False\n",
    "                elif c not in num:\n",
    "                    return False\n",
    "            return True\n",
    "        # 按照e分割\n",
    "        if s[0]=='e' or s[-1]=='e':\n",
    "            return False\n",
    "        e_list=s.split('e')\n",
    "        # 有e\n",
    "        if len(e_list)>2:\n",
    "            return False\n",
    "        if len(e_list)==2:\n",
    "            if not isInt(e_list[-1]):\n",
    "                return False\n",
    "        s=e_list[0]\n",
    "        # s应该是整数或小数\n",
    "        # 如果是整数\n",
    "        if isInt(s):\n",
    "            return True\n",
    "        # s是小数\n",
    "        # .213排除\n",
    "        if s[0]=='.':\n",
    "            if isInt(s[1:]) and (s[1] in num):\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        # +23123.排除\n",
    "        if s[-1]=='.':\n",
    "            if isInt(s[:-1]):\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        p_list=s.split('.')\n",
    "        if len(p_list)!=2:\n",
    "            return False\n",
    "        return (isInt(p_list[0]) or p_list[0] in \"+-\") and isInt(p_list[1])\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from enum import Enum\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        State = Enum(\"State\", [\n",
    "            \"STATE_INITIAL\",\n",
    "            \"STATE_INT_SIGN\",\n",
    "            \"STATE_INTEGER\",\n",
    "            \"STATE_POINT\",\n",
    "            \"STATE_POINT_WITHOUT_INT\",\n",
    "            \"STATE_FRACTION\",\n",
    "            \"STATE_EXP\",\n",
    "            \"STATE_EXP_SIGN\",\n",
    "            \"STATE_EXP_NUMBER\",\n",
    "            \"STATE_END\"\n",
    "        ])\n",
    "        Chartype = Enum(\"Chartype\", [\n",
    "            \"CHAR_NUMBER\",\n",
    "            \"CHAR_EXP\",\n",
    "            \"CHAR_POINT\",\n",
    "            \"CHAR_SIGN\",\n",
    "            \"CHAR_SPACE\",\n",
    "            \"CHAR_ILLEGAL\"\n",
    "        ])\n",
    "\n",
    "        def toChartype(ch: str) -> Chartype:\n",
    "            if ch.isdigit():\n",
    "                return Chartype.CHAR_NUMBER\n",
    "            elif ch.lower() == \"e\":\n",
    "                return Chartype.CHAR_EXP\n",
    "            elif ch == \".\":\n",
    "                return Chartype.CHAR_POINT\n",
    "            elif ch == \"+\" or ch == \"-\":\n",
    "                return Chartype.CHAR_SIGN\n",
    "            elif ch == \" \":\n",
    "                return Chartype.CHAR_SPACE\n",
    "            else:\n",
    "                return Chartype.CHAR_ILLEGAL\n",
    "        \n",
    "        transfer = {\n",
    "            State.STATE_INITIAL: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_INITIAL,\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT,\n",
    "                Chartype.CHAR_SIGN: State.STATE_INT_SIGN\n",
    "            },\n",
    "            State.STATE_INT_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT\n",
    "            },\n",
    "            State.STATE_INTEGER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT_WITHOUT_INT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION\n",
    "            },\n",
    "            State.STATE_FRACTION: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_EXP: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SIGN: State.STATE_EXP_SIGN\n",
    "            },\n",
    "            State.STATE_EXP_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "            State.STATE_EXP_NUMBER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_END: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "        }\n",
    "\n",
    "        st = State.STATE_INITIAL\n",
    "        for ch in s:\n",
    "            typ = toChartype(ch)\n",
    "            if typ not in transfer[st]:\n",
    "                return False\n",
    "            st = transfer[st][typ]\n",
    "        \n",
    "        return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER, State.STATE_END]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        num_flag = False\n",
    "        dot_flag = False\n",
    "        e_flag = False\n",
    "\n",
    "        s = s.strip()\n",
    "        if len(s) == 0:\n",
    "            return False\n",
    "\n",
    "        index = 0\n",
    "        while(index <= len(s)-1):\n",
    "            if ord(s[index]) <= ord(\"9\") and ord(s[index]) >= ord(\"0\"):\n",
    "                num_flag = True\n",
    "            elif s[index] == \".\":\n",
    "                if dot_flag is False and e_flag is False:\n",
    "                    dot_flag = True\n",
    "                else:\n",
    "                    return False\n",
    "            elif s[index] in \"eE\":\n",
    "                if e_flag is False and num_flag is True:\n",
    "                    e_flag = True\n",
    "                    num_flag = False\n",
    "                else:\n",
    "                    return False\n",
    "            elif s[index] in \"+-\":\n",
    "                if index == 0:\n",
    "                    pass\n",
    "                else:\n",
    "                    if index-1 >= 0 and s[index-1] in \"eE\" and \\\n",
    "                        index+1 <= len(s)-1 and ord(s[index+1]) <= ord(\"9\") and ord(s[index+1]) >= ord(\"0\"):\n",
    "                        pass\n",
    "                    else:\n",
    "                        return False\n",
    "\n",
    "            else:\n",
    "                return False\n",
    "            index += 1\n",
    "        return num_flag\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        ###构建状态转移机\n",
    "        states = [\n",
    "        {' ': 0, 's': 1, 'd': 2 ,'.': 4},\n",
    "        {'d': 2,'.': 4},\n",
    "        {'d': 2, '.': 3, 'e': 5, ' ':8},\n",
    "        {'d': 3, 'e': 5, ' ': 8},\n",
    "        {'d' : 3},\n",
    "        {'s' : 6, 'd': 7},\n",
    "        {'d': 7},\n",
    "        {'d': 7,' ': 8},\n",
    "        {' ': 8}\n",
    "        ]\n",
    "        p = 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd'\n",
    "            elif c in '+-': t = 's'\n",
    "            elif c in 'eE': t = 'e'\n",
    "            elif c in '. ': t = c\n",
    "            else: t = '?'\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2,3,7,8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from enum import Enum\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        State = Enum(\"State\", [\n",
    "            \"STATE_INITIAL\",\n",
    "            \"STATE_INT_SIGN\",\n",
    "            \"STATE_INTEGER\",\n",
    "            \"STATE_POINT\",\n",
    "            \"STATE_POINT_WITHOUT_INT\",\n",
    "            \"STATE_FRACTION\",\n",
    "            \"STATE_EXP\",\n",
    "            \"STATE_EXP_SIGN\",\n",
    "            \"STATE_EXP_NUMBER\",\n",
    "            \"STATE_END\"\n",
    "        ])\n",
    "        Chartype = Enum(\"Chartype\", [\n",
    "            \"CHAR_NUMBER\",\n",
    "            \"CHAR_EXP\",\n",
    "            \"CHAR_POINT\",\n",
    "            \"CHAR_SIGN\",\n",
    "            \"CHAR_SPACE\",\n",
    "            \"CHAR_ILLEGAL\"\n",
    "        ])\n",
    "\n",
    "        def toChartype(ch: str) -> Chartype:\n",
    "            if ch.isdigit():\n",
    "                return Chartype.CHAR_NUMBER\n",
    "            elif ch.lower() == \"e\":\n",
    "                return Chartype.CHAR_EXP\n",
    "            elif ch == \".\":\n",
    "                return Chartype.CHAR_POINT\n",
    "            elif ch == \"+\" or ch == \"-\":\n",
    "                return Chartype.CHAR_SIGN\n",
    "            elif ch == \" \":\n",
    "                return Chartype.CHAR_SPACE\n",
    "            else:\n",
    "                return Chartype.CHAR_ILLEGAL\n",
    "        \n",
    "        transfer = {\n",
    "            State.STATE_INITIAL: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_INITIAL,\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT,\n",
    "                Chartype.CHAR_SIGN: State.STATE_INT_SIGN\n",
    "            },\n",
    "            State.STATE_INT_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT\n",
    "            },\n",
    "            State.STATE_INTEGER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT_WITHOUT_INT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION\n",
    "            },\n",
    "            State.STATE_FRACTION: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_EXP: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SIGN: State.STATE_EXP_SIGN\n",
    "            },\n",
    "            State.STATE_EXP_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "            State.STATE_EXP_NUMBER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_END: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "        }\n",
    "\n",
    "        st = State.STATE_INITIAL\n",
    "        for ch in s:\n",
    "            typ = toChartype(ch)\n",
    "            if typ not in transfer[st]:\n",
    "                return False\n",
    "            st = transfer[st][typ]\n",
    "        \n",
    "        return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER, State.STATE_END]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from enum import Enum\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        s = s.strip()\n",
    "        State = Enum(\"State\", [\n",
    "            \"STATE_INITIAL\",\n",
    "            \"STATE_INT_SIGN\",\n",
    "            \"STATE_INTEGER\",\n",
    "            \"STATE_POINT\",\n",
    "            \"STATE_POINT_WITHOUT_INT\",\n",
    "            \"STATE_FRACTION\",\n",
    "            \"STATE_EXP\",\n",
    "            \"STATE_EXP_SIGN\",\n",
    "            \"STATE_EXP_NUMBER\",\n",
    "            \"STATE_END\"\n",
    "        ])\n",
    "        Chartype = Enum(\"Chartype\", [\n",
    "            \"CHAR_NUMBER\",\n",
    "            \"CHAR_EXP\",\n",
    "            \"CHAR_POINT\",\n",
    "            \"CHAR_SIGN\",\n",
    "            \"CHAR_ILLEGAL\"\n",
    "        ])\n",
    "\n",
    "        def toChartype(ch):\n",
    "            if ch.isdigit():\n",
    "                return Chartype.CHAR_NUMBER\n",
    "            elif ch.lower() == \"e\":\n",
    "                return Chartype.CHAR_EXP\n",
    "            elif ch == \".\":\n",
    "                return Chartype.CHAR_POINT\n",
    "            elif ch == \"+\" or ch == \"-\":\n",
    "                return Chartype.CHAR_SIGN\n",
    "            else:\n",
    "                return Chartype.CHAR_ILLEGAL\n",
    "        \n",
    "\n",
    "        transfer = {\n",
    "            State.STATE_INITIAL: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT,\n",
    "                Chartype.CHAR_SIGN: State.STATE_INT_SIGN\n",
    "            },\n",
    "            State.STATE_INT_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT\n",
    "            },\n",
    "            State.STATE_INTEGER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT\n",
    "            },\n",
    "            State.STATE_POINT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP\n",
    "            },\n",
    "            State.STATE_POINT_WITHOUT_INT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION\n",
    "            },\n",
    "            State.STATE_FRACTION: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP\n",
    "            },\n",
    "            State.STATE_EXP: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SIGN: State.STATE_EXP_SIGN\n",
    "            },\n",
    "            State.STATE_EXP_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "            State.STATE_EXP_NUMBER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "        }\n",
    "\n",
    "        st = State.STATE_INITIAL\n",
    "        for ch in s:\n",
    "            ch_type = toChartype(ch)\n",
    "            if ch_type not in transfer[st]:\n",
    "                return False\n",
    "            st = transfer[st][ch_type]\n",
    "        \n",
    "        return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER]\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        states = [\n",
    "            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'\n",
    "            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'\n",
    "            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'\n",
    "            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'\n",
    "            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')\n",
    "            { 's': 6, 'd': 7 },                 # 5. 'e'\n",
    "            { 'd': 7 },                         # 6. 'sign' after 'e'\n",
    "            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'\n",
    "            { ' ': 8 }                          # 8. end with 'blank'\n",
    "        ]\n",
    "        p = 0                           # start with state 0\n",
    "        for c in s:\n",
    "            if '0' <= c <= '9': t = 'd' # digit\n",
    "            elif c in \"+-\": t = 's'     # sign\n",
    "            elif c in \"eE\": t = 'e'     # e or E\n",
    "            elif c in \". \": t = c       # dot, blank\n",
    "            else: t = '?'               # unknown\n",
    "            if t not in states[p]: return False\n",
    "            p = states[p][t]\n",
    "        return p in (2, 3, 7, 8)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from enum import Enum\n",
    "\n",
    "class Solution:\n",
    "    def validNumber(self, s: str) -> bool:\n",
    "        State = Enum(\"State\", [\n",
    "            \"STATE_INITIAL\",\n",
    "            \"STATE_INT_SIGN\",\n",
    "            \"STATE_INTEGER\",\n",
    "            \"STATE_POINT\",\n",
    "            \"STATE_POINT_WITHOUT_INT\",\n",
    "            \"STATE_FRACTION\",\n",
    "            \"STATE_EXP\",\n",
    "            \"STATE_EXP_SIGN\",\n",
    "            \"STATE_EXP_NUMBER\",\n",
    "            \"STATE_END\"\n",
    "        ])\n",
    "        Chartype = Enum(\"Chartype\", [\n",
    "            \"CHAR_NUMBER\",\n",
    "            \"CHAR_EXP\",\n",
    "            \"CHAR_POINT\",\n",
    "            \"CHAR_SIGN\",\n",
    "            \"CHAR_SPACE\",\n",
    "            \"CHAR_ILLEGAL\"\n",
    "        ])\n",
    "\n",
    "        def toChartype(ch: str) -> Chartype:\n",
    "            if ch.isdigit():\n",
    "                return Chartype.CHAR_NUMBER\n",
    "            elif ch.lower() == \"e\":\n",
    "                return Chartype.CHAR_EXP\n",
    "            elif ch == \".\":\n",
    "                return Chartype.CHAR_POINT\n",
    "            elif ch == \"+\" or ch == \"-\":\n",
    "                return Chartype.CHAR_SIGN\n",
    "            elif ch == \" \":\n",
    "                return Chartype.CHAR_SPACE\n",
    "            else:\n",
    "                return Chartype.CHAR_ILLEGAL\n",
    "        \n",
    "        transfer = {\n",
    "            State.STATE_INITIAL: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_INITIAL,\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT,\n",
    "                Chartype.CHAR_SIGN: State.STATE_INT_SIGN\n",
    "            },\n",
    "            State.STATE_INT_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT\n",
    "            },\n",
    "            State.STATE_INTEGER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_INTEGER,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_POINT: State.STATE_POINT,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_POINT_WITHOUT_INT: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION\n",
    "            },\n",
    "            State.STATE_FRACTION: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_FRACTION,\n",
    "                Chartype.CHAR_EXP: State.STATE_EXP,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_EXP: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SIGN: State.STATE_EXP_SIGN\n",
    "            },\n",
    "            State.STATE_EXP_SIGN: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER\n",
    "            },\n",
    "            State.STATE_EXP_NUMBER: {\n",
    "                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "            State.STATE_END: {\n",
    "                Chartype.CHAR_SPACE: State.STATE_END\n",
    "            },\n",
    "        }\n",
    "\n",
    "        st = State.STATE_INITIAL\n",
    "        for ch in s:\n",
    "            typ = toChartype(ch)\n",
    "            if typ not in transfer[st]:\n",
    "                return False\n",
    "            st = transfer[st][typ]\n",
    "        \n",
    "        return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER, State.STATE_END]"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
